from importlib.metadata import version
import tiktoken

print("tiktoken version:", version("tiktoken"))

tokenizer = tiktoken.get_encoding('gpt2')

text = (
    "Hello, do you like tea? <|endoftext|> In the sunlit terraces"
     "of someunknownPlace."
)
integers = tokenizer.encode(text, allowed_special={"<|endoftext|>"})
print(integers)
# [15496, 11, 466, 345, 588, 8887, 30, 220, 50256, 554, 262, 4252, 18250, 8812, 2114, 1659, 617, 34680, 27271, 13]

strings = tokenizer.decode(integers)
print(strings)
# Hello, do you like tea? <|endoftext|> In the sunlit terracesof someunknownPlace.


"""
1.<|endoftext|>词元被分配了一个较大的词元ID，即50256

2.BPE: byte pair encoding 字节对编码，NLP中一种常见的数据压缩算法
BPE分词器可以正确地编码和解码未知单词，比如“someunknownPlace”。
BPE算法的原理是将不在预定义词汇表中的单词分解为更小的子词单元甚至单个字符，从而能够处理词汇表之外的单词。
因此，得益于BPE算法，如果分词器在分词过程中遇到不熟悉的单词，它可以将其表示为子词词元或字符序列。
将未知单词分解为单个字符的能力确保了分词器以及用其训练的大语言模型能够处理任何文本，即使文本中包含训练数据中不存在的单词。
BPE算法被广泛应用于多种语言模型中，如GPT-2、RoBERTa、XLM和FlauBERT等。这些模型利用BPE算法处理文本数据，以提高模型的泛化能力和处理未知词汇的能力。

"""


# 作业：
# 尝试使用tiktoken库中的BPE分词器对未知单词“Akwirw ier”进行分词，并打印所有词元ID。
# 然后，对得到的列表中的每个整数应用decode函数，以重现图2-11中的映射。
# 最后，对这些词元ID调用decode方法，检查它能否还原原始输入“Akwirw ier”。

text = "Akwirw ier"
encoded_ints = tokenizer.encode(text, allowed_special={"<|endoftext|>"})
print(encoded_ints)

# for encoded_int in encoded_ints:
#     # print(tokenizer.decode([encoded_int]))
#     print(tokenizer.decode(list([encoded_int])))
print([tokenizer.decode([encoded_int]) for encoded_int in encoded_ints])

decoded_str = tokenizer.decode(encoded_ints)
print(decoded_str)

